home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- * is provided to you without charge, and with no warranty. You may give *
- * away copies of JOVE, including sources, provided that this notice is *
- * included in all the files. *
- ***************************************************************************/
-
- /* Contains commands that deal with creating, selecting, killing and
- listing buffers, and buffer modes, and find-file, etc. */
-
- #include "jove.h"
- #include "ctype.h"
- #include "disp.h"
- #ifdef IPROCS
- # include "fp.h"
- # include "iproc.h"
- #endif
-
- #ifdef MAC
- # include "mac.h"
- #else
- # include <stat.h>
- #endif
-
- private void
- setbname proto((Buffer *, char *));
-
- private char *Mainbuf = "Main",
- *NoName = "Sans un nom!";
-
- Buffer *world = NULL, /* First in the list */
- *curbuf = NULL, /* pointer into world for current buffer */
- *lastbuf = NULL; /* Last buffer we were in so we have a default
- buffer during a select buffer. */
-
- /* Toggle BIT in the current buffer's minor mode flags. If argument is
- supplied, a positive one always turns on the mode and zero argument
- always turns it off. */
-
- void
- TogMinor(bit)
- int bit;
- {
- if (is_an_arg()) {
- if (arg_value() == 0)
- curbuf->b_minor &= ~bit;
- else
- curbuf->b_minor |= bit;
- } else
- curbuf->b_minor ^= bit;
- UpdModLine = YES;
- }
-
- /* Creates a new buffer, links it at the end of the buffer chain, and
- returns it. */
-
- private Buffer *free_bufs = NULL;
-
- private Buffer *
- buf_alloc()
- {
- register Buffer *b,
- *lastbp;
-
- lastbp = NULL;
- for (b = world; b != NULL; b = b->b_next)
- lastbp = b;
-
- if (free_bufs != NULL) {
- b = free_bufs;
- free_bufs = b->b_next;
- } else {
- b = (Buffer *) emalloc(sizeof (Buffer));
- }
- if (lastbp)
- lastbp->b_next = b;
- else
- world = b;
- b->b_first = NULL;
- b->b_next = NULL;
- #ifdef MAC
- b->Type = BUFFER; /* kludge, but simplifies menu handlers */
- b->Name = NULL;
- #endif
- return b;
- }
-
- /* Makes a buffer and initializes it. Obsolete. Used to take two
- arguments, a buffer name and a file name. */
-
- private Buffer *
- mak_buf()
- {
- register Buffer *newb;
- register int i;
-
- newb = buf_alloc();
- newb->b_fname = NULL;
- newb->b_name = NoName;
- set_ino(newb);
- newb->b_marks = NULL;
- newb->b_themark = 0; /* Index into markring */
- /* No marks yet */
- for (i = 0; i < NMARKS; i++)
- newb->b_markring[i] = NULL;
- newb->b_modified = NO;
- newb->b_type = B_FILE; /* File until proven SCRATCH */
- newb->b_ntbf = NO;
- newb->b_minor = 0;
- newb->b_major = TEXT;
- newb->b_first = NULL;
- newb->b_map = NULL;
- #ifdef IPROCS
- newb->b_process = NULL;
- #endif
- initlist(newb);
- #ifdef MAC
- Bufchange = YES;
- #endif
- return newb;
- }
-
- void
- ReNamBuf()
- {
- register char *new = NULL,
- *prompt = ProcFmt,
- *second = "%s already exists; new name? ";
-
- for (;;) {
- new = ask((char *)NULL, prompt, new);
- if (!buf_exists(new))
- break;
- prompt = second;
- }
- setbname(curbuf, new);
- }
-
- void
- FindFile()
- {
- register char *name;
- char fnamebuf[FILESIZE];
-
- name = ask_file((char *)NULL, curbuf->b_fname, fnamebuf);
- SetABuf(curbuf);
- SetBuf(do_find(curwind, name, NO));
- }
-
- private void
- mkbuflist(bnamp, ebnamp)
- register char **bnamp;
- char **ebnamp;
- {
- register Buffer *b;
-
- for (b = world; b != NULL; b = b->b_next) {
- if (b->b_name != NULL) {
- *bnamp++ = b->b_name;
- if (bnamp >= ebnamp)
- complain("too many buffers to list");
- }
- }
- *bnamp = NULL;
- }
-
- char *
- ask_buf(def)
- Buffer *def;
- {
- char *bnames[100];
- register char *bname;
- register int offset;
- char prompt[100];
-
- if (def != NULL && def->b_name != NULL) {
- swritef(prompt, sizeof(prompt), ": %f (default %s) ",
- def->b_name);
- } else {
- swritef(prompt, sizeof(prompt), ProcFmt);
- }
- mkbuflist(bnames, &bnames[sizeof(bnames) / sizeof(*bnames)]);
- offset = complete(bnames, prompt, RET_STATE);
- if (offset == EOF)
- complain((char *)NULL);
- if (offset == ORIGINAL || offset == AMBIGUOUS) {
- bname = Minibuf;
- } else if (offset == NULLSTRING) {
- if (def == NULL)
- complain((char *)NULL);
- bname = def->b_name;
- } else {
- if (offset < 0)
- complain((char *)NULL);
- bname = bnames[offset];
- }
-
- return bname;
- }
-
- void
- BufSelect()
- {
- register char *bname;
-
- bname = ask_buf(lastbuf);
- SetABuf(curbuf);
- SetBuf(do_select(curwind, bname));
- }
-
- #ifdef MSDOS
-
- private void
- BufNSelect(n)
- int n;
- {
- register Buffer *b;
-
- for (b = world; b != NULL; b = b->b_next) {
- if (b->b_name != NULL) {
- if (n == 0) {
- SetABuf(curbuf);
- SetBuf(do_select(curwind, b->b_name));
- return;
- }
- n -= 1;
- }
- }
- complain("[No such buffer]");
- }
-
- void Buf0Select() { BufNSelect(0); }
- void Buf1Select() { BufNSelect(1); }
- void Buf2Select() { BufNSelect(2); }
- void Buf3Select() { BufNSelect(3); }
- void Buf4Select() { BufNSelect(4); }
- void Buf5Select() { BufNSelect(5); }
- void Buf6Select() { BufNSelect(6); }
- void Buf7Select() { BufNSelect(7); }
- void Buf8Select() { BufNSelect(8); }
- void Buf9Select() { BufNSelect(9); }
-
- #endif /* MSDOS */
-
- private void
- defb_wind(b)
- register Buffer *b;
- {
- register Window *w = fwind;
- char *alt;
-
- if (lastbuf == b || lastbuf == NULL) {
- lastbuf = NULL;
- alt = (b->b_next != NULL) ? b->b_next->b_name : Mainbuf;
- } else
- alt = lastbuf->b_name;
-
- do {
- if (w->w_bufp == b) {
- if (one_windp() || alt != Mainbuf)
- (void) do_select(w, alt);
- else {
- Window *save = w->w_next;
-
- del_wind(w);
- w = save->w_prev;
- }
- }
- w = w->w_next;
- } while (w != fwind || w->w_bufp == b);
- }
-
- private Buffer *
- getNMbuf()
- {
- register Buffer *delbuf;
- register char *bname;
-
- bname = ask_buf(curbuf);
- if ((delbuf = buf_exists(bname)) == NULL)
- complain("[No such buffer]");
- if (delbuf->b_modified)
- confirm("%s modified, are you sure? ", bname);
- return delbuf;
- }
-
- void
- BufErase()
- {
- register Buffer *delbuf;
-
- if ((delbuf = getNMbuf()) != NULL) {
- initlist(delbuf);
- delbuf->b_modified = NO;
- }
- }
-
- /* Free a buffer structure.
- * The actual struct is preserved to reduce the damage
- * from dangling references to it. They seem to be pervasive.
- * We try to reset enough that a dangling reference will be useless.
- */
-
- private void
- kill_buf(delbuf)
- register Buffer *delbuf;
- {
- register Buffer *b,
- *lastb = NULL;
-
- #ifdef IPROCS
- pbuftiedp(delbuf); /* check for lingering processes */
- #endif
- /* clean up windows associated with this buffer */
- if (delbuf == curbuf)
- curbuf = NULL;
- if (delbuf == lastbuf)
- lastbuf = curbuf; /* even if NULL */
- defb_wind(delbuf);
- if (curbuf == NULL)
- SetBuf(curwind->w_bufp);
-
- /* unlink the buffer */
- for (b = world; b != NULL; lastb = b, b = b->b_next)
- if (b == delbuf)
- break;
- if (lastb)
- lastb->b_next = delbuf->b_next;
- else
- world = delbuf->b_next;
-
- #ifndef MAC
- if (perr_buf == delbuf) {
- ErrFree();
- perr_buf = NULL;
- }
- #endif
-
- lfreelist(delbuf->b_first);
- delbuf->b_first = delbuf->b_dot = delbuf->b_last = NULL;
- if (delbuf->b_name) {
- free((UnivPtr) delbuf->b_name);
- delbuf->b_name = NULL;
- }
- if (delbuf->b_fname) {
- free((UnivPtr) delbuf->b_fname);
- delbuf->b_fname = NULL;
- }
- flush_marks(delbuf);
- delbuf->b_marks = NULL;
-
- delbuf->b_next = free_bufs;
- free_bufs = delbuf;
- #ifdef MAC
- Bufchange = YES;
- delbuf->Name = NULL;
- #endif
- }
-
- /* offer to kill some buffers */
-
- void
- KillSome()
- {
- register Buffer *b,
- *next;
- Buffer *oldb;
- register char *y_or_n;
-
- for (b = world; b != NULL; b = next) {
- next = b->b_next;
- if (yes_or_no_p("Kill %s? ", b->b_name) == NO)
- continue;
- if (IsModified(b)) {
- y_or_n = ask("No", "%s modified; should I save it? ", b->b_name);
- if (CharUpcase(*y_or_n) == 'Y') {
- oldb = curbuf;
- SetBuf(b);
- SaveFile();
- SetBuf(oldb);
- }
- }
- kill_buf(b);
- }
- }
-
- void
- BufKill()
- {
- Buffer *b;
-
- if ((b = getNMbuf()) == NULL)
- return;
- kill_buf(b);
- }
-
- private char *
- line_cnt(b, buf, size)
- register Buffer *b;
- char *buf;
- size_t size;
- {
- register int nlines = 0;
- register Line *lp;
-
- for (lp = b->b_first; lp != NULL; lp = lp->l_next, nlines++)
- ;
- swritef(buf, size, "%d", nlines);
- return buf;
- }
-
- private const char *const TypeNames[] = {
- NULL,
- "Scratch",
- "File",
- "Process",
- };
-
- void
- BufList()
- {
- register char *fmt = "%-2s %-5s %-11s %-1s %-*s %-s";
- register Buffer *b;
- int bcount = 1, /* To give each buffer a number */
- buf_width = 11;
- char nbuf[10];
-
- for (b = world; b != NULL; b = b->b_next)
- buf_width = max(buf_width, (int)strlen(b->b_name));
-
- TOstart("Buffer list", TRUE); /* true means auto-newline */
-
- Typeout("(* means buffer needs saving)");
- Typeout("(+ means file hasn't been read yet)");
- Typeout(NullStr);
- Typeout(fmt, "NO", "Lines", "Type", NullStr, buf_width, "Name", "File");
- Typeout(fmt, "--", "-----", "----", NullStr, buf_width, "----", "----");
- for (b = world; b != NULL; b = b->b_next) {
- Typeout(fmt, itoa(bcount++),
- line_cnt(b, nbuf, sizeof(nbuf)),
- TypeNames[b->b_type],
- IsModified(b) ? "*" :
- b->b_ntbf ? "+" : NullStr,
- buf_width,
- /* For the * (variable length field) */
- b->b_name,
- filename(b));
-
- if (TOabort)
- break;
- }
- TOstop();
- }
-
- private void
- bufname(b)
- register Buffer *b;
- {
- char tmp[100],
- *cp;
- int try = 1;
-
- if (b->b_fname == NULL)
- complain("[No file name]");
- cp = basename(b->b_fname);
- strcpy(tmp, cp);
- while (buf_exists(tmp)) {
- swritef(tmp, sizeof(tmp), "%s.%d", cp, try);
- try += 1;
- }
- setbname(b, tmp);
- }
-
- void
- initlist(b)
- register Buffer *b;
- {
- lfreelist(b->b_first);
- b->b_first = b->b_dot = b->b_last = NULL;
- (void) listput(b, b->b_first);
-
- SavLine(b->b_dot, NullStr);
- b->b_char = 0;
- AllMarkSet(b, b->b_dot, 0);
- if (b == curbuf)
- getDOT();
- }
-
- /* Returns pointer to buffer with name NAME, or if NAME is a string of digits
- returns the buffer whose number equals those digits. Otherwise, returns
- NULL. */
-
- Buffer *
- buf_exists(name)
- register char *name;
- {
- register Buffer *bp;
- int n;
-
- if (name == NULL)
- return NULL;
-
- for (bp = world; bp != NULL; bp = bp->b_next)
- if (strcmp(bp->b_name, name) == 0)
- return bp;
-
- /* Doesn't match any names. Try for a buffer number... */
-
- if (chr_to_int(name, 10, YES, &n) != INT_BAD) {
- for (bp = world; n > 1; bp = bp->b_next) {
- if (bp == NULL)
- break;
- n -= 1;
- }
- return bp;
- }
-
- return NULL;
- }
-
- /* Returns buffer pointer with a file name NAME, if one exists. Stat's the
- file and compares inodes, in case NAME is a link, as well as the actual
- characters that make up the file name. */
-
- Buffer *
- file_exists(name)
- register char *name;
- {
- struct stat stbuf;
- register struct stat *s = &stbuf;
- register Buffer *b = NULL;
- char fnamebuf[FILESIZE];
-
- #ifdef MSDOS
- strlwr(name);
- #endif /* MSDOS */
- if (name) {
- PathParse(name, fnamebuf);
- if (stat(fnamebuf, s) == -1)
- s->st_ino = 0;
- for (b = world; b != NULL; b = b->b_next) {
- if (
- #ifndef MSDOS
- (b->b_ino != 0 && b->b_ino == s->st_ino &&
- b->b_dev != 0 && b->b_dev == s->st_dev) ||
- #endif /* MSDOS */
- (b->b_fname != NULL &&
- strcmp(b->b_fname, fnamebuf) == 0))
- break;
- }
- }
- return b;
- }
-
- private void
- setbname(b, name)
- register Buffer *b;
- register char *name;
- {
- UpdModLine = YES; /* Kludge ... but speeds things up considerably */
- if (name != NULL) {
- if (b->b_name == NoName)
- b->b_name = NULL;
- b->b_name = freealloc((UnivPtr) b->b_name, strlen(name) + 1);
- strcpy(b->b_name, name);
- } else {
- b->b_name = NULL;
- }
- #ifdef MAC
- Bufchange = YES;
- #endif
- }
-
- void
- setfname(b, name)
- register Buffer *b;
- register char *name;
- {
- char wholename[FILESIZE],
- oldname[FILESIZE],
- *oldptr = oldname;
- Buffer *save = curbuf;
-
- SetBuf(b);
- UpdModLine = YES; /* Kludge ... but speeds things up considerably */
- if (b->b_fname == NULL)
- oldptr = NULL;
- else
- strcpy(oldname, b->b_fname);
- if (name) {
- #ifdef MSDOS
- strlwr(name);
- #endif /* MSDOS */
- PathParse(name, wholename);
- curbuf->b_fname = freealloc((UnivPtr) curbuf->b_fname, strlen(wholename) + 1);
- strcpy(curbuf->b_fname, wholename);
- } else
- b->b_fname = NULL;
- DoAutoExec(curbuf->b_fname, oldptr);
- curbuf->b_mtime = curbuf->b_dev = curbuf->b_ino = 0; /* until they're known. */
- SetBuf(save);
- #ifdef MAC
- Bufchange = YES;
- #endif
- }
-
- void
- set_ino(b)
- register Buffer *b;
- {
- struct stat stbuf;
-
- if (b->b_fname == NULL || stat(pr_name(b->b_fname, NO), &stbuf) == -1) {
- b->b_dev = 0;
- b->b_ino = 0;
- b->b_mtime = 0;
- } else {
- b->b_dev = stbuf.st_dev;
- b->b_ino = stbuf.st_ino;
- b->b_mtime = stbuf.st_mtime;
- }
- }
-
- /* Find the file `fname' into buf and put in in window `w' */
-
- Buffer *
- do_find(w, fname, force)
- register Window *w;
- register char *fname;
- bool force;
- {
- register Buffer *b;
-
- b = file_exists(fname);
- if (b == NULL) {
- b = mak_buf();
- setfname(b, fname);
- bufname(b);
- set_ino(b);
- b->b_ntbf = YES;
- }
- if (force) {
- Buffer *oldb = curbuf;
-
- SetBuf(b); /* this'll read the file */
- SetBuf(oldb);
- }
- if (w)
- tiewind(w, b);
- return b;
- }
-
- /* set alternate buffer */
-
- void
- SetABuf(b)
- Buffer *b;
- {
- if (b != NULL)
- lastbuf = b;
- }
-
-
- /* check to see if BP is a valid buffer pointer */
- private bool
- valid_bp(bp)
- register Buffer *bp;
- {
- register Buffer *b;
-
- for (b = world; b != NULL; b = b->b_next)
- if (b == bp)
- return YES;
- return NO;
- }
-
- void
- SetBuf(newbuf)
- register Buffer *newbuf;
- {
- if (newbuf == curbuf || newbuf == NULL)
- return;
-
- if (!valid_bp(newbuf))
- complain("Internal error: (0x%x) is not a valid buffer pointer!", newbuf);
- lsave();
- curbuf = newbuf;
- curline = newbuf->b_dot;
- curchar = newbuf->b_char;
- getDOT();
- /* do the read now ... */
- if (curbuf->b_ntbf)
- read_file(curbuf->b_fname, NO);
- #ifdef MAC
- Modechange = YES;
- #endif
- }
-
- Buffer *
- do_select(w, name)
- register Window *w;
- register char *name;
- {
- register Buffer *new;
-
- if ((new = buf_exists(name)) == NULL) {
- new = mak_buf();
- setfname(new, (char *)NULL);
- setbname(new, name);
- }
- if (w)
- tiewind(w, new);
- return new;
- }
-
- void
- buf_init()
- {
- SetBuf(do_select(curwind, Mainbuf));
- }
-